<?php
/**
 * +----------------------------------------------------------------------
 * | Author: 罗极
 * +----------------------------------------------------------------------
 * | Description: ControllerProxy.php
 * +----------------------------------------------------------------------
 * | User: Administrator Date: 8/25/ 0025 Time: 9:01
 * +----------------------------------------------------------------------
 */

namespace Framework\App;

use Framework\Controller\Abstracts\AbstractController;
use Framework\App\Constant\AOPKey;
use Framework\Event\Abstracts\EventBase;
use Framework\Event\ControllerListener;
use Framework\Router\Constant\DefaultKey;

class ControllerProxy
{
    private $controller;
    private $eventManager; // todo 需要加入EventManager吗

    public function __construct(AbstractController $controller)
    {
        $this->controller   = $controller;
    }

    public function __call($name, $arg)
    {
        if(!is_callable([$this->controller, $name])) {
            throw new \Framework\Controller\Exception\NonCallableException(sprintf(
                'Action不可调用 : [%s]',
                get_class($this->controller).'::'.$name
            ));
        }

        $baseActionName = str_replace(DefaultKey::ActionSuffix, '', $name);

        $bootstrapActionName = AOPKey::Bootstrap;

        if(is_callable([$this->controller, $bootstrapActionName])) {
            call_user_func_array([$this->controller, $bootstrapActionName], $arg);
        }

        $beforeActionName = AOPKey::Before.ucfirst($baseActionName);

        if(is_callable([$this->controller, $beforeActionName])) {
            call_user_func_array([$this->controller, $beforeActionName], $arg);
        }


        $return =  call_user_func_array([$this->controller, $name], $arg);

        $afterActionName = AOPKey::After.ucfirst($baseActionName);
        if(is_callable([$this->controller, $afterActionName])) {
            call_user_func_array([$this->controller,$afterActionName], $arg);
        }

        return $return;
    }

}